/*
	This script file is part of the Sonic 3 A.I.R. script software distribution.
	Copyright (C) 2017-2024 by Eukaryot

	Published under the GNU GPLv3 open source software license, see license.txt
	or https://www.gnu.org/licenses/gpl-3.0.en.html
*/



//# address-hook(0x0330c8) end(0x0330e8)
function void fn0330c8()
{
	A1 = 0xffffb000
	A4 = A0 + 0x30
	fn0330ee()

	A1 = 0xffffb04a
	A4 = A0 + 0x3a
	fn0330ee()

	if (u8[A0 + 0x30] + objA0.value3a == 0)
	{
		CheckForUnloadObject()
	}
}


//# address-hook(0x0330ee) end(0x0330f6)
function void fn0330ee()
{
	// Targets:
	//  - 0x033102	-> u8[A4] = 0x00
	//  - 0x03318e	-> u8[A4] = 0x02
	//  - 0x0331ca	-> u8[A4] = 0x04
	//  - 0x03320e	-> u8[A4] = 0x06
	call tableLookupAddress(0x0330fa, u8[A4])
}


//# address-hook(0x033102) end(0x03318c)
function void fn033102()
{
	if (debug_mode.state == 0)
	{
		D0.u16 = objA1.position.x.u16 - objA0.position.x.u16 + 0x40
		D1.u16 = objA1.position.y.u16 - objA0.position.y.u16 + 0x10
		if (D0.u16 < 0x80 && D1.u16 < 0x20 && u8[A1 + 0x2e] == 0)
		{
			u8[A4] += 2

			u16[A1 + 0x1c] = 0x0800
			objA1.velocity.x = 0
			objA1.velocity.y = 0
			objA1.state = char.state.ROLLING
			u8[A1 + 0x2a] &= ~char.flag.PUSHING
			u8[A1 + 0x2a] |= char.flag.IN_AIR
			u8[A1 + 0x2e] = (control_flag.DISABLE_INTERACTION | control_flag.DISABLE_UPDATE)

			u8[A4 + 0x01] = 0
			D1 = 0x30
			if (D0.u16 < 0x40)
			{
				D1.s16 = -D1.s16
				u8[A4 + 0x01] = 0x80
			}
			D1.u16 += objA0.position.x.u16
			objA1.position.x.u16 = D1.u16
			objA1.position.y.u16 = objA0.position.y.u16

			playSound(SFX_ROLL)
		}
	}
}


//# address-hook(0x03318e) end(0x0331c8)
function void fn03318e()
{
	D0.u8 = u8[A4 + 0x01]
	u8[A4 + 0x01] += 0x08
	LookupSinCos()
	D1.s16 >>= 3
	D0.u16 = D1.u16
	D1.s16 >>= 1
	D0.u16 += D1.u16
	D0.u16 += objA0.position.x.u16
	objA1.position.x.u16 = D0.u16
	D0 = (u8[0xfffffe21] & 0x01) ? 0x80 : 0
	if (D0.u8 == u8[A4 + 0x01])
	{
		u8[A4] += 0x02
		u16[A4 + 0x02] = 0xc0
	}
}


//# address-hook(0x0331ca) end(0x03320c)
function void fn0331ca()
{
	D0.u8 = u8[A4 + 0x01]
	u8[A4 + 0x01] += 0x0c
	LookupSinCos()
	D1.s16 >>= 3
	D0.u16 = D1.u16
	D1.s16 >>= 1
	D0.u16 += D1.u16
	D0.u16 += objA0.position.x.u16
	objA1.position.x.u16 = D0.u16
	objA1.position.y.u16 += 2

	--u16[A4 + 0x02]
	if (u16[A4 + 0x02] == 0)
	{
		D1.u16 = objA0.position.x.u16 - objA1.position.x.u16
		D0 = (D1.s16 < 0) ? 1 : 0
		D0.u8 += objA0.subtype2c
		fn033272()
		u8[A4] += 2
	}
}


//# address-hook(0x03320e) end(0x033270)
function void fn03320e()
{
	--u8[A4 + 0x02]
	if (s8[A4 + 0x02] < 0)
	{
		A2 = u32[A4 + 0x06]
		D4.u16 = u16[(A2+=2)-2]
		objA1.position.x.u16 = D4.u16
		D5.u16 = u16[(A2+=2)-2]
		objA1.position.y.u16 = D5.u16
		u32[A4 + 0x06] = A2
		u16[A4 + 0x04] -= 4
		if (u16[A4 + 0x04] == 0)
		{
			objA1.position.y.u16 &= 0x0fff
			u8[A4] = 0
			u8[A1 + 0x2e] = 0
			u8[A1 + 0x40] = 0
		}
		else
		{
			D4.u16 = u16[(A2+=2)-2]
			D5.u16 = u16[(A2+=2)-2]
			D2.u16 = 0x0c00

			fn0332a2()
			return
		}
	}

	D0.s32 = objA1.velocity.x << 8
	D2 = objA1.position.x + D0
	D0.s32 = objA1.velocity.y << 8
	D3 = objA1.position.y + D0
	objA1.position.x = D2
	objA1.position.y = D3
}


//# address-hook(0x033272) end(0x03329e)
function void fn033272()
{
	D0.u16 = (D0.u16 & 0x0f) * 2

	// Targets:
	//  - 0x033328	-> D0.u16 = 0x00
	//  - 0x033336	-> D0.u16 = 0x02
	//  - 0x033352	-> D0.u16 = 0x06
	A2 = tableLookupAddress(0x033320, D0.u16)

	u16[A4 + 0x04] = u16[A2] - 4
	objA1.position.x.u16 = u16[A2+2]
	objA1.position.y.u16 = u16[A2+4]
	A2 += 6
	u32[A4 + 0x06] = A2
	D4.u16 = u16[(A2+=2)-2]
	D5.u16 = u16[(A2+=2)-2]
	D2.u16 = 0x0c00
	fn0332a2()
}


//# address-hook(0x0332a2) end(0x03331e)
function void fn0332a2()
{
	D0 = 0
	D3.u16 = D2.u16
	D0.u16 = D4.u16 - objA1.position.x.u16
	if (D0.s16 < 0)
	{
		D0.s16 = -D0.s16
		D2.s16 = -D2.s16
	}
	D1 = 0
	D1.u16 = D5.u16 - objA1.position.y.u16
	if (D1.s16 < 0)
	{
		D1.s16 = -D1.s16
		D3.s16 = -D3.s16
	}
	if (D1.u16 >= D0.u16)
	{
		D1.u16 = D5.u16 - objA1.position.y.u16
		D1 = (D1 << 16)
		D1.s16 = D1.s32 / D3.s16
		D0 = 0
		D0.u16 = D4.u16 - objA1.position.x.u16
		if (D0.u16 != 0)
		{
			D0 = (D0 << 16) + (D0 >> 16)
			D0.s16 = D0.s32 / D1.s16
		}

		objA1.velocity.x = D0.u16
		objA1.velocity.y = D3.u16
		if (D1.s16 < 0)
		{
			D1.s16 = -D1.s16
		}
		u16[A4 + 0x02] = D1.u16
	}
	else
	{
		D0 = 0
		D0.u16 = D4.u16 - objA1.position.x.u16
		D0 = (D0 << 16) + (D0 >> 16)
		D0.s16 = D0.s32 / D2.s16
		D1 = 0
		D1.u16 = D5.u16 - objA1.position.y.u16
		if (D1.u16 != 0)
		{
			D1 = (D1 << 16) + (D1 >> 16)
			D1.s16 = D1.s32 / D0.s16
		}

		objA1.velocity.y = D1.u16
		objA1.velocity.x = D2.u16
		if (D0.s16 < 0)
		{
			D0.s16 = -D0.s16
		}
		u16[A4 + 0x02] = D0.u16
	}
}



// Closing door over the right exit

//# address-hook(0x031c9e) end(0x031cc4)
function void fn031c9e()
{
	objA0.mapping_offset = 0x230dcc
	objA0.sprite_attributes = (sprite_attribute.PALETTE.LINE2 | 0x03f0)
	objA0.render_flags |= render_flag.WORLD
	objA0.sprite_priority = 0x80
	objA0.box_size.x = 0x20
	objA0.box_size.y = 0x08

	objA0.update_address = 0x031cca
	fn031cca()
}


//# address-hook(0x031cca) end(0x031cf4)
function void fn031cca()
{
	A1 = 0xffffb000
	fn031cfa()

	A1 = 0xffffb04a
	fn031cfa()

	D1.u16 = 0x20
	D3.u16 = 0x09
	D4.u16 = objA0.position.x.u16
	PlatformCheckClimbOn()

	Object.animationUpdate(0x031d2e)
	DrawOrUnloadObject()
}


//# address-hook(0x031cfa) end(0x031d2c)
function void fn031cfa()
{
	D0.u16 = objA0.position.x.u16 - objA1.position.x.u16 + 0x20
	if (D0.u16 < 0x40)
	{
		D0.u16 = objA0.position.y.u16 - objA1.position.y.u16 + 0x20
		if (D0.u16 < 0x20)
		{
			objA0.state = 0x01
			playSound(0x76)
		}
	}
}
